﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Perceiveit.Xml
{
    public partial class XEntityCollection<TItem>
    {

        private class XEntityCollectionEnumerator : IEnumerator<TItem>
        {
            private XEntityCollection<TItem> _col;
            private int _changeinitial;
            private int _offset;
            private TItem _current;
            private bool _ended = false;

            public XEntityCollectionEnumerator(XEntityCollection<TItem> col)
            {
                if (null == col)
                    throw new ArgumentNullException("col");

                _col = col;
                this.Reset();
            }

            public TItem Current
            {
                get
                {
                    this.AssertCollectionChange();
                    this.AssertCurrentState();

                    return _current; 
                }
            }

            object System.Collections.IEnumerator.Current
            {
                get { return this.Current; }
            }

            public bool MoveNext()
            {
                this.AssertCollectionChange();
                _offset++;
                if (_offset < _col.Count)
                {
                    _current = _col.GetItemAt(_offset);
                    _ended = false;
                }
                else
                {
                    _ended = true;
                    _current = null;
                }
                return !_ended;
            }

            public void Reset()
            {
                _changeinitial = this._col.GetChangeIncrement();
                _offset = -1;
                _current = null;
                _ended = false;
            }

            void IDisposable.Dispose()
            {
                this.Reset();
                this._col = null;
            }

            private void AssertCurrentState()
            {
                if (_ended)
                    throw new InvalidOperationException("The enumerator has gone past the end of the collection. Cannot call current on this");
                if (_offset < 0)
                    throw new InvalidOperationException("the enumerator has not been moved to the first item. Call MoveNext() before starting to enumerate over a collection");
            }

            private void AssertCollectionChange()
            {
                if (null == _col)
                    throw new InvalidOperationException("This enumerator has been disposed and cannot be reused");

                if (_changeinitial != _col.GetChangeIncrement())
                    throw new System.InvalidOperationException("The collection has changed since the enumerator started. Cannot continue");
            }
        }


        
    }
}
